use aes::Aes128;
use ctr;
use ctr::cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};

type Aes128Ctr = ctr::Ctr128<aes::Aes128>;

pub fn encrypt(plaindata: &Vec<u8>, key: &[u8], nonce: &[u8]) -> Vec<u8> {
    exchange(plaindata, key, nonce)
}

pub fn decrypt(cipherdata: &Vec<u8>, key: &[u8], nonce: &[u8]) -> Vec<u8> {
    exchange(cipherdata, key, nonce)
}

fn exchange(data: &Vec<u8>, key: &[u8], nonce: &[u8]) -> Vec<u8> {
    let mut result = data.clone();
    Aes128Ctr::new(key.into(), nonce.into()).apply_keystream(&mut result);
    result
}


#[cfg(test)]
mod tests {
    use hex_literal::hex;
    #[test]
    fn it_works() {
        let key = hex!("013F65A3AE564CA02D5215C36D71DBB3");
        let iv = hex!("013F6543AE564CA01D5215C36D71DBB3");

        let plaindata = b"test aes ctr";

        let cipherdata = super::encrypt(&plaindata.to_vec(), &key, &iv);
        let plaindata2 = super::decrypt(&cipherdata, &key, &iv);
        println!("{:?}", cipherdata);
        println!("{:?}", plaindata2);
        assert_eq!(cipherdata.len(), plaindata.len());
        assert_eq!(plaindata.to_vec() , plaindata2);
    }
}